<?php

namespace App\Http\Controllers;

use App\Project;
use App\AwardApplicationFormData;
use App\ExpertGroup;
use App\Doc;
use App\ProjectAttachment;
use App\Services\AwardService;
use App\Services\LogService;
use App\Services\CommonService;
use App\Services\ProjectService;
use App\Services\ReviewService;
use App\Services\WorkflowService;
use App\User;
use Auth, Request;
use App\Services\AuthService;
use Illuminate\Support\Facades\Storage;
use Session;

class WebController extends Controller
{
    /**
     * @var AwardService
     */
    private $awardSvc;

    public function __construct()
    {
        $this->middleware('auth', [
            'except' => [
                'index',
                'apply',
                'applyRegister',
                'applyLogin',
                'nominate',
                'nominateLogin',
                'showPrint',
                'admin',
                'adminLogin',
                'adminOrgCertify',
                'review',
                'reviewLogin',
                'meetingReviewLogin',
                'viewForm',
                'viewAttachments',
            ],
        ]);
        $this->authSvc = new AuthService;
        $this->awardSvc = new AwardService;
        $this->logSvc = new LogService;
        $this->commonSvc = new CommonService;
        $this->projSvc = new ProjectService();
    }

    public function index()
    {
        return view('index');
    }

    public function logout()
    {
        $user = Request::user();
        $this->logSvc->sinfo('退出', null, $user, null);
        $this->authSvc->logout();
        $redirectTo = '/';

        if ($user->isAdmin()) {
            $redirectTo = '/admin/login';
        }
        return redirect($redirectTo);
    }

    public function apply()
    {
        $user = Request::user();
        // session可能过期，过期时重新登录
        $loginRole = Session::get('login_role');
        if ($loginRole == null) {
            $redirectTo = '/apply/login';
        } elseif ($user && $user->isApplicant()) {
            $redirectTo = '/home';
        } else {
            $redirectTo = '/apply/login';
        }
        return redirect($redirectTo);
    }

    public function applyLogin()
    {
        $ip = Request::getClientIp();
        $errorSessionKey = 'count_of_login_error_' . $ip;
        $countOfLoginError = 0;
        if (Session::has($errorSessionKey)) {
            $countOfLoginError = Session::get($errorSessionKey);
        }
        return view('apply.login', ['countOfLoginError' => $countOfLoginError]);
    }

    public function review()
    {
        $user = Request::user();
        // session可能过期，过期时重新登录
        $loginRole = Session::get('login_role');
        if ($loginRole == null) {
            $redirectTo = '/review/login';
        } elseif ($user && $user->isReviewer()) {
            $redirectTo = '/review/list-projects?aside_key=待评审项目列表';
        } else {
            $redirectTo = '/review/login';
        }
        return redirect($redirectTo);
    }

    public function reviewLogin()
    {
        $ip = Request::getClientIp();
        $errorSessionKey = 'count_of_login_error_' . $ip;
        $countOfLoginError = 0;
        if (Session::has($errorSessionKey)) {
            $countOfLoginError = Session::get($errorSessionKey);
        }
        return view('review.login', ['countOfLoginError' => $countOfLoginError]);
    }

    public function homeReview()
    {
        return redirect('/review/list-projects?aside_key=待评审项目列表');
    }

    public function meetingReviewLogin()
    {
        $ip = Request::getClientIp();
        $errorSessionKey = 'count_of_login_error_' . $ip;
        $countOfLoginError = 0;
        if (Session::has($errorSessionKey)) {
            $countOfLoginError = Session::get($errorSessionKey);
        }
        return view('meeting-review/login', ['countOfLoginError' => $countOfLoginError]);
    }

    public function applyRegister()
    {
        return view('apply.register');
    }

    public function nominate()
    {
        $user = Request::user();
        $loginRole = Session::get('login_role');
        if ($loginRole == null) {
            $redirectTo = 'nominate/login';
        } elseif ($user && $user->isNominator()) {
            $redirectTo = '/home';
        } else {
            $redirectTo = '/nominate/login';
        }
        return redirect($redirectTo);
    }

    public function nominateLogin()
    {
        return view('nominate.login');
    }

    public function home()
    {
        $user = Request::user();
        if ($user) {
            $loginRole = Session::get('login_role');
            if ($loginRole === 'applicant') {
                return redirect('/home/apply');
            } elseif ($loginRole === 'nominator') {
                return redirect('/home/nominate');
            }
        }
        return redirect('/');
    }

    public function homeApply()
    {
        $user = Request::user();
        $applications = $this->awardSvc->getUserApplications($user, 'applicant');
        $applications = $applications->toArray();
        $nominators = $this->awardSvc->getNominators($user);
        $nominators = $nominators->toArray();

        // 是否开启申报
        $workflowService = new WorkflowService();
        $DeclarePhaseStatus = $workflowService->atPhase(WorkflowService::PHASE_APPLY);

        // 是否结束形式审查
        $workflowSvc = new WorkflowService();
        $AtPhaseFormalReview = $workflowSvc->atPhase(WorkflowService::PHASE_FORMAL_REVIEW);

        $applicationOpenAwardIds = $this->awardSvc->getApplicationOpenAwardIds();

        return view('home.apply', [
            'user' => $user,
            'DeclarePhaseStatus' => $DeclarePhaseStatus,
            'AtPhaseFormalReview' => $AtPhaseFormalReview,
            'applicationOpenAwardIds' => $applicationOpenAwardIds,
            'applications' => $applications,
            'nominators' => $nominators]);
    }

    public function homeNominate()
    {
        $user = Request::user();
        $applications = $this->awardSvc->getUserApplications($user, 'nominator');
        $applications = $applications->toArray();
        return view('home.nominate', ['user' => $user, 'applications' => $applications]);
    }

    public function homeFillForm()
    {
        $id = Request::get('id');
        if (empty($id)) die('No id'); // 非正常访问
        $user = Request::user();
        $application = Project::find($id);
        if (empty($application)) {
            die('该奖项不存在');
        }
        if (!$this->authSvc->canUserAccessProject($user, $application)) {
            die('没有权限查看该内容');
        }
        $canEdit = $this->authSvc->canUserEditAwardApplication($user, $application);
        $formView = $this->awardSvc->getAwardFormView($application->award_id, $canEdit);
        $applicationFormData = AwardApplicationFormData::find($application->id);
        $formData = json_decode($applicationFormData->form_data);
        if (empty($formData)) {
            $formData = new \stdClass;
        }
        $type = '';
        $application = $this->awardSvc->getWaitingForReviewAwardInfoById($application->id);

        return view($formView, ['user' => $user, 'formData' => $formData, 'canEdit' => $canEdit, 'type' => $type, 'application' => $application]);
    }

    public function homeWonAwards()
    {

        $user = Request::user();
        $applications = $this->awardSvc->getUserApplications($user, 'won_awards');
        $applications = $applications->toArray();
        $nominators = $this->awardSvc->getNominators($user);
        $nominators = $nominators->toArray();

        // 是否开启申报
        $workflowService = new WorkflowService();
        $DeclarePhaseStatus = $workflowService->atPhase(WorkflowService::PHASE_APPLY);

        // 是否结束形式审查
        $workflowSvc = new WorkflowService();
        $AtPhaseFormalReview = $workflowSvc->atPhase(WorkflowService::PHASE_FORMAL_REVIEW);

        $applicationOpenAwardIds = $this->awardSvc->getApplicationOpenAwardIds();

        return view('home.won-awards', [
            'user' => $user,
            'DeclarePhaseStatus' => $DeclarePhaseStatus,
            'AtPhaseFormalReview' => $AtPhaseFormalReview,
            'applicationOpenAwardIds' => $applicationOpenAwardIds,
            'applications' => $applications,
            'nominators' => $nominators]);

        $user = Request::user();
    }

    public function homeDocs()
    {
        $user = Request::user();
        $docs = Doc::all();
        return view('home.docs', ['user' => $user, 'docs' => $docs]);
    }

    public function showPrint()
    {
        $id = Request::get('award_id');
        if (empty($id)) die('No id'); // 非正常访问
        $application = Project::find($id);
        $awardInfo = $this->awardSvc->getAwardInfo($application->award_id);

        // 校验提名信息
        if ($awardInfo['nomination_required']) {
            if (empty($application['nominator_ids'])) die; // 非正常提交
            $nominatorIdsArr = explode(",", $application->nominator_ids);
            $nominatorNamesArr = $this->awardSvc->getNominatorsByIds($nominatorIdsArr);
            $nominatorNamesString = implode(',', $nominatorNamesArr->toArray());
        } else {
            $nominatorNamesString = '';
        }
        $printView = $this->awardSvc->getAwardPrintView($application->award_id);
        $applicationFormData = AwardApplicationFormData::find($application->id);
        $formData = json_decode($applicationFormData->form_data);
        if (empty($formData)) {
            $formData = new \stdClass;
        }
        $barcode = (string)date("YmdHis") . $id;
        $barcodeImg = $this->commonSvc->getBarCodeImg($barcode, 'C39');
        $returnData = [
            'formData' => $formData,
            'nominatorNamesString' => $nominatorNamesString,
            'barcode' => $barcode, 'barcodeImg' => $barcodeImg
        ];
        return view($printView, $returnData);
    }

    public function adminFormalReviewWaitingForReview($awardId)
    {
        $statusId = [Project::STATUS_FORMAL_REVIEW_TO_REVIEW];
        $user = Request::user();
        $applications = $this->awardSvc->getApplicationsByStatusId($statusId);
        $applications = $applications->toArray();
        $applications = array_values(array_filter($applications, function($item) use($awardId) {
            return $item->award_id == $awardId;
        }));
//        dd($applications);
        $nominators = $this->awardSvc->getNominators($user);
        $nominators = $nominators->toArray();
        $statisticsInfo = $this->awardSvc->getAdminAsideStatisticsInfo();
        return view('admin.formal-review', ['awardId' => $awardId, 'user' => $user, 'applications' => $applications, 'nominators' => $nominators, 'viewStatusId' => Project::STATUS_FORMAL_REVIEW_TO_REVIEW, 'statisticsInfo' => $statisticsInfo]);
    }

    public function adminFormalReviewPassed()
    {
        $statusId = [Project::STATUS_ASSIGN_REVIEW_TO_ASSIGN, Project::STATUS_ASSIGN_REVIEW_TO_SUBMIT_ASSIGN];
        $user = Request::user();
        $applications = $this->awardSvc->getApplicationsByStatusId($statusId);
        $applications = $applications->toArray();
        $nominators = $this->awardSvc->getNominators($user);
        $nominators = $nominators->toArray();
        $statisticsInfo = $this->awardSvc->getAdminAsideStatisticsInfo();
        return view('admin.formal-review', [
            'user' => $user, 'applications' => $applications, 'nominators' => $nominators,
            'viewStatusId' => Project::STATUS_ASSIGN_REVIEW_TO_ASSIGN, 'statisticsInfo' => $statisticsInfo]);
    }

    public function homeContactUs()
    {
        $user = Request::user();
        return view('home.contact-us', ['user' => $user]);
    }

    public function reviewWaitingForReview()
    {
        $user = Request::user();
        if (!$user->isReviewer()) {
            die('非评审专家无权查看');
        }
        $reviewAwardsInfo = $this->awardSvc->getWaitingForReviewAwardInfoByExpert($user);
        $asideGroupsInfo = $this->awardSvc->getMyGroupsInfo($user);
        return view('review.review', ['user' => $user, 'reviewAwardsInfo' => $reviewAwardsInfo, 'asideGroupsInfo' => $asideGroupsInfo]);
    }

    public function adminWaitingForExpertReview()
    {
        $statusId = ['A5', 'A6'];
        $user = Request::user();
        $applications = $this->awardSvc->getApplicationsByStatusId($statusId);
        $applications = $applications->toArray();
        $nominators = $this->awardSvc->getNominators($user);
        $nominators = $nominators->toArray();
        $statisticsInfo = $this->awardSvc->getAdminAsideStatisticsInfo();
        return view('admin.waiting-for-expert-review', ['user' => $user, 'applications' => $applications, 'nominators' => $nominators, 'viewStatusId' => $statusId, 'statisticsInfo' => $statisticsInfo]);

    }

    public function reviewMyGroup()
    {
        $groupId = Request::get('group_id');
        if (empty($groupId)) die('No group_id'); // 非正常访问
        $user = Request::user();
        if (!$user->isReviewer()) {
            die('非评审专家无权查看');
        }
        $expertGroup = ExpertGroup::find($groupId);
        if (empty($expertGroup)) {
            return $this->json(['ok' => false, 'message' => '该评审小组不存在']);
        }
        $asideGroupsInfo = $this->awardSvc->getMyGroupsInfo($user);
        $groupScoreDetailsInfo = $this->awardSvc->getExpertGroupDetailsInfo($user, $expertGroup);
        return view('review.my-group', [
            'user' => $user,
            'asideGroupsInfo' => $asideGroupsInfo,
            'group_id' => $groupId,
            'groupScoreDetailsInfo' => $groupScoreDetailsInfo
        ]);
    }

    public function showFormInfoReadonly()
    {
        $id = Request::get('id');
        $type = Request::get('type');
        if (empty($id)) die('No id'); // 非正常访问
        $user = Request::user();
        $application = Project::find($id);
        if (empty($application)) {
            die('该奖项不存在');
        }
        if (!$this->authSvc->canUserAccessProject($user, $application)) {
            die('没有权限查看该内容');
        }
        $canEdit = $this->authSvc->canUserEditAwardApplication($user, $application);
        $formView = $this->awardSvc->getAwardFormView($application->award_id, $canEdit);
        $applicationFormData = AwardApplicationFormData::find($application->id);
        $application = $this->awardSvc->getWaitingForReviewAwardInfoById($application->id);
        $formData = json_decode($applicationFormData->form_data);
        if (empty($formData)) {
            $formData = new \stdClass;
        }
        return view($formView, ['user' => $user, 'type' => $type, 'formData' => $formData, 'canEdit' => $canEdit, 'application'=> $application]);
    }

    public function viewForm()
    {
        $id = Request::get('id');
        $user = Request::user();
        $project = Project::find($id);
        if (empty($project)) {
            die('该项目不存在');
        }
        if (!$this->authSvc->canUserAccessProject($user, $project)) {
            die('没有权限查看该内容');
        }
        if ($user->isReviewer()) {
            (new ReviewService())->onViewApplication($user->id, $id);
        }
        $view = "home.view-form-{$project->award_id}";
        $formData = $this->projSvc->getProjectFormData($project->id);
        return view($view, ['user' => $user, 'project'=> $project, 'formData' => $formData]);
    }

    public function viewAttachments()
    {
        $projectId = Request::get('project_id');
        $user = Request::user();
        $project = Project::find($projectId);
        if (empty($project)) {
            die('该项目不存在');
        }
        if (!$this->authSvc->canUserAccessProject($user, $project)) {
            die('没有权限查看该内容');
        }
        if ($user->isReviewer()) {
            (new ReviewService())->onViewAttachments($user->id, $projectId);
        }
        $view = "home.view-attachments";
        $attachments = ProjectAttachment::where('project_id', $project->id)
            ->where('sub_file_count', 0)
            ->where('filesize', '>', 0)
            ->get();
        $attachments->each(function($attachment) use($project) {
            $attachment->type_name = config('app.award_attachment_type_name')[$project->award_id][$attachment->type];
        });
        $viewData = [
            'typeNames' => array_values(config('app.award_attachment_type_name')[$project->award_id]),
            'attachments' => $attachments,
        ];
        return view($view, $viewData);
    }

}
